home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / gfx / 3d / rayshade40_enh2.lha / ENHANCE / zbuf.doc < prev   
Text File  |  1992-04-28  |  5KB  |  135 lines

  1.         *** Adding Z Buffer output to Rayshade 4.0 ***
  2.  
  3.     Mark Maimone, mwm@cs.cmu.edu    (BITNET: mwm%cs.cmu.edu@CARNEGIE)
  4.  
  5.                 18 March 1992
  6.  
  7.     I've made a preliminary attempt at getting Rayshade to output depth
  8. information in addition to rendered images.  I need this information since I
  9. want to use Rayshade to generate test images for a stereo algorithm.  Having
  10. the "true" depth means I can test how accurately my stereo algorithm
  11. reconstructs it (depth) from only the stereo pair of 2D images without
  12. knowing the inherent 3D structure.
  13.  
  14.     My technique is quite basic.  I rely on the anti-aliasing scheme to
  15. sample the pixels, and remember the distance from the Eye to the nearest
  16. object along each generated ray.  Of all these distances associated with a
  17. pixel, I arbitrarily choose the one nearest to the eye to denote the "true"
  18. distance.
  19.  
  20.     This scheme has several problems (and I'm sure others will find
  21. more).  It doesn't return the distance of the object that occupies *most* of
  22. the pixel, it merely returns the distance of the object it finds nearest to
  23. the eye; it doesn't matter if it only occupies 5% of the pixel.  It lets the
  24. antialiasing scheme choose which rays are relevant; a bad antialiasing
  25. scheme may well yield a bad Z buffer.  It treats transparent objects as
  26. opaque (changing this *should* only require adding a very simple test in
  27. trace_pixel(), but I don't know enough about the internals yet).  It assumes
  28. all distances are positive (this, at least, should be a reasonable
  29. assumption).
  30.  
  31.     The changes were realized entirely within the
  32. "rayshade-4.0/rayshade" directory.  No changes were made to the libraries.
  33. Adding the Z buffer to rayshade involves several small changes to files in
  34. that directory, plus the addition of two more (short) source files, zbuf.c
  35. and zbuf.h.
  36.  
  37. ======== COMMAND LINE INTERFACE
  38.  
  39.     Very easy.  Just run rayshade with the "-z filename" option to write
  40. the Z buffer to the named file.  You must name some file, it won't write to
  41. stdout.
  42.  
  43. ======== IMPLEMENTATION
  44.  
  45.     Rayshade-4.0 already computes everything needed to generate the Z
  46. buffer, but it throws the information away.  I've added an external Float
  47. array   (zbuffer in zbuf.c)   to store the distance to the nearest object in
  48. each pixel.  You must have enough memory available for a Float array with
  49. the same dimensions as the window being rendered.
  50.  
  51.     I put a hook into the routine where Rayshade finds the "first"
  52. object hit by a given ray (trace_pixel() in rayshade/raytrace.c).  That hook
  53. calls ZbufAdd() to store the current distance in global array   zbuffer.
  54. ZbufAdd() maps the Float index values to ints by using floor(pix+0.5) for
  55. both X and Y.
  56.  
  57. ======== FILE FORMAT
  58.  
  59.     The first few lines in the file are comments describing the source
  60. of the data.  After that, the depth information follows, with each line
  61. representing a single pixel:
  62.  
  63.     <int x-coord> <int y-coord> <Float distance>
  64.  
  65. A distance of -1 means the pixel denotes background.  The file is ordered by
  66. scanline, with a blank line separating scanlines.  This format is ideally
  67. suited for viewing the depth map using GNUplot (see comments in zbuf.c).
  68.  
  69.     Here's a sample output file:
  70.  
  71. # Depth Map for Rayshade output file
  72. # Input RAY file: "../Examples/planet.ray"
  73. # Resolution for this rendering is 50x50
  74. # window from (0,0) to (49,49)
  75. # Index 0: 11412 hits
  76. 0 0 -1
  77. 0 1 -1
  78. 0 2 -1
  79. 0 3 -1
  80.     .        [ I deleted many lines for brevity ]
  81.     .
  82. 12 13 -1
  83. 12 14 -1
  84. 12 15 -1
  85. 12 16 3.75485
  86. 12 17 3.60294
  87. 12 18 3.52262
  88. 12 19 3.46714
  89. 12 20 3.42647
  90. 12 21 3.40308
  91.  
  92. ======== COMMENTS
  93.  
  94.     Please post any comments to the rayshade-users@cs.princeton.edu
  95. mailing list, or if you prefer you may send them directly to me at
  96. mwm@cs.cmu.edu.  Any comments are welcome, especially ones of the form "your
  97. scheme for computing the Z buffer is useless because...."
  98.  
  99.                     Mark Maimone
  100.                     CMU Computer Science
  101.                     mwm@cs.cmu.edu
  102.  
  103.  
  104. ======== EXAMPLES
  105.  
  106.     % rayshade -R 50 50 -z zbuf.dat Examples/balls.ray > balls.rle
  107.     % gnuplot
  108.     gnuplot> set term x11        [or whatever you're on]
  109.     gnuplot> set sample 2500    [for a 50x50 image]
  110.     gnuplot> set parametric        [needed to plot 3D data]
  111.     gnuplot> splot 'zbuf.dat' with lines
  112.                     [gives a nice height map grid]
  113.     gnuplot> help set view        [info on changing viewpoint]
  114.     gnuplot> set view 45, 45    [a sample viewpoint]
  115.     gnuplot> quit
  116.  
  117.    Warning!  Distances are expected to always be positive, so background
  118.    pixels are represented by a distance of ZBUF_INF (i.e., -1).  To get
  119.    nice looking GNUplot output you should replace all -1's with the maximum
  120.    distance.  On UNIX:
  121.  
  122.     % rayshade -R 50 50 -z zbuf.dat Examples/planet.ray > balls.rle
  123.     % awk 'BEGIN {max = -1} NF == 3 { if ($3 > max) max = $d} END \
  124.         {print max}' < zbuf.dat        [this gives you the max]
  125.     3.69359
  126.     % sed s/-1/3.69359/g < zbuf.dat | awk 'NF == 3 { print $1" "$2" -"$3 \
  127.         ; next} {print}' > zbuf.plot    [replace -1 with max, make all
  128.                          distances negative so the
  129.                          plot appears rightside up]
  130.     % gnuplot
  131.         .
  132.         .
  133.     gnuplot> set zrange [-3.7:0]
  134.     gnuplot> splot 'zbuf.plot'
  135.